// PDF转换服务 - 将Office文档转换为PDF格式
const fs = require('fs');
const path = require('path');
const { exec } = require('child_process');
const { promisify } = require('util');
const database = require('../../src/config/database');
const pool = database.default || database.pool;

// 使用环境变量中的soffice命令
const SOFFICE_COMMAND = 'soffice';

class PdfConversionService {
  constructor() {
    this.libreOfficePath = null;
  }

  // 检查LibreOffice是否可用
  async checkLibreOfficeAvailable() {
    if (this.libreOfficePath) {
      return this.libreOfficePath;
    }

    try {
      await new Promise((resolve, reject) => {
        exec(`${SOFFICE_COMMAND} --version`, (error, stdout, stderr) => {
          if (error) {
            reject(error);
          } else {
            resolve(stdout);
          }
        });
      });
      
      console.log('LibreOffice可用，使用环境变量中的soffice命令');
      this.libreOfficePath = SOFFICE_COMMAND;
      return SOFFICE_COMMAND;
    } catch (error) {
      throw new Error('LibreOffice不可用，请确保soffice命令在环境变量PATH中');
    }
  }

  // 检查转换器是否可用
  async checkOfficeConverterAvailable() {
    try {
      await this.checkLibreOfficeAvailable();
      return true;
    } catch (error) {
      console.warn('LibreOffice不可用:', error.message);
      return false;
    }
  }

  // 自定义的PDF转换函数
  async convertToPdfWithCustomPath(buffer, originalName = 'document') {
    const libreOfficePath = await this.checkLibreOfficeAvailable();
    
    return new Promise((resolve, reject) => {
      // 创建临时文件，使用安全的文件名
      const tempDir = require('os').tmpdir();
      const cleanName = originalName
        .replace(/[<>:"/\\|?*]/g, '') // 移除Windows不允许的字符
        .replace(/[""'']/g, '') // 移除各种引号
        .replace(/\s+/g, '_') // 将空格替换为下划线
        .substring(0, 20); // 限制长度
      const inputFileName = `temp_${cleanName}_${Date.now()}_${Math.random().toString(36).substr(2, 9)}.docx`;
      const inputFilePath = path.join(tempDir, inputFileName);
      const outputDir = tempDir;
      
      // 写入临时文件
      fs.writeFileSync(inputFilePath, buffer);
      
      // 构建转换命令
      const cmd = `${libreOfficePath} --headless --convert-to pdf "${inputFilePath}" --outdir "${outputDir}"`;
      
      console.log('执行转换命令:', cmd);
      
      exec(cmd, (error, stdout, stderr) => {
        // 清理输入文件
        try {
          fs.unlinkSync(inputFilePath);
        } catch (e) {
          console.warn('清理临时文件失败:', e.message);
        }
        
        if (error) {
          console.error('转换命令执行失败:', error.message);
          reject(error);
          return;
        }
        
        // 查找生成的PDF文件
        const pdfFileName = path.parse(inputFileName).name + '.pdf';
        const pdfFilePath = path.join(outputDir, pdfFileName);
        
        try {
          if (fs.existsSync(pdfFilePath)) {
            const pdfBuffer = fs.readFileSync(pdfFilePath);
            // 清理PDF文件
            fs.unlinkSync(pdfFilePath);
            resolve(pdfBuffer);
          } else {
            reject(new Error('PDF文件生成失败'));
          }
        } catch (readError) {
          reject(readError);
        }
      });
    });
  }

  // 将Word文档转换为PDF
  async convertWordToPdf(filePath, originalName) {
    try {
      console.log('开始转换Word文档为PDF:', originalName);

      if (!fs.existsSync(filePath)) {
        throw new Error('源文件不存在');
      }

      // 读取源文件
      const docxBuffer = fs.readFileSync(filePath);
      
      try {
        // 使用自定义路径进行转换
        console.log('使用LibreOffice进行转换...');
        const pdfBuffer = await this.convertToPdfWithCustomPath(docxBuffer, originalName);
        
        // 生成PDF文件名
        const pdfFileName = this.generatePdfFileName(originalName);
        const pdfPath = path.join(path.dirname(filePath), pdfFileName);
        
        // 保存PDF文件
        fs.writeFileSync(pdfPath, pdfBuffer);
        
        console.log('Word文档转换为PDF成功:', pdfFileName);
        
        return {
          success: true,
          pdfPath: pdfPath,
          pdfFileName: pdfFileName,
          pdfUrl: `/uploads/${pdfFileName}`,
          originalSize: docxBuffer.length,
          pdfSize: pdfBuffer.length
        };
      } catch (conversionError) {
        console.warn('LibreOffice转换失败，使用备用方案:', conversionError.message);
        return this.createPdfPlaceholder(filePath, originalName, 'Word文档');
      }
    } catch (error) {
      console.error('Word转PDF失败:', error);
      return {
        success: false,
        error: error.message
      };
    }
  }

  // 将PowerPoint文档转换为PDF
  async convertPowerPointToPdf(filePath, originalName) {
    try {
      console.log('开始转换PowerPoint文档为PDF:', originalName);

      if (!fs.existsSync(filePath)) {
        throw new Error('源文件不存在');
      }

      // 读取源文件
      const pptBuffer = fs.readFileSync(filePath);
      
      try {
        // 使用自定义路径进行转换
        console.log('使用LibreOffice进行转换...');
        const pdfBuffer = await this.convertToPdfWithCustomPath(pptBuffer, originalName);
        
        // 生成PDF文件名
        const pdfFileName = this.generatePdfFileName(originalName);
        const pdfPath = path.join(path.dirname(filePath), pdfFileName);
        
        // 保存PDF文件
        fs.writeFileSync(pdfPath, pdfBuffer);
        
        console.log('PowerPoint文档转换为PDF成功:', pdfFileName);
        
        return {
          success: true,
          pdfPath: pdfPath,
          pdfFileName: pdfFileName,
          pdfUrl: `/uploads/${pdfFileName}`,
          originalSize: pptBuffer.length,
          pdfSize: pdfBuffer.length
        };
      } catch (conversionError) {
        console.warn('LibreOffice转换失败，使用备用方案:', conversionError.message);
        return this.createPdfPlaceholder(filePath, originalName, 'PowerPoint演示文稿');
      }
    } catch (error) {
      console.error('PowerPoint转PDF失败:', error);
      return {
        success: false,
        error: error.message
      };
    }
  }

  // 生成PDF文件名
  generatePdfFileName(originalName) {
    const nameWithoutExt = path.parse(originalName).name;
    // 清理文件名，移除特殊字符
    const cleanName = nameWithoutExt
      .replace(/[<>:"/\\|?*]/g, '') // 移除Windows不允许的字符
      .replace(/[""'']/g, '') // 移除各种引号
      .replace(/\s+/g, '_') // 将空格替换为下划线
      .substring(0, 50); // 限制长度
    const timestamp = Date.now();
    const randomSuffix = Math.round(Math.random() * 1000);
    return `${cleanName}-${timestamp}-${randomSuffix}.pdf`;
  }

  // 创建PDF占位符（当LibreOffice不可用时）
  async createPdfPlaceholder(filePath, originalName, documentType) {
    try {
      const stats = fs.statSync(filePath);
      const fileSize = (stats.size / 1024).toFixed(1);
      
      // 创建一个HTML页面作为PDF预览的替代方案
      const placeholderHtml = this.generatePlaceholderHtml(originalName, documentType, fileSize);
      
      // 生成HTML文件名，确保路径安全
      const htmlFileName = this.generatePdfFileName(originalName).replace('.pdf', '.html');
      const htmlPath = path.join(path.dirname(filePath), htmlFileName);
      
      // 确保目录存在
      const htmlDir = path.dirname(htmlPath);
      if (!fs.existsSync(htmlDir)) {
        fs.mkdirSync(htmlDir, { recursive: true });
      }
      
      // 保存HTML文件
      fs.writeFileSync(htmlPath, placeholderHtml, 'utf8');
      
      console.log('创建PDF占位符成功:', htmlFileName);
      
      return {
        success: true,
        isPlaceholder: true,
        pdfPath: htmlPath,
        pdfFileName: htmlFileName,
        pdfUrl: `/uploads/${htmlFileName}`,
        originalSize: stats.size,
        pdfSize: Buffer.byteLength(placeholderHtml, 'utf8')
      };
    } catch (error) {
      console.error('创建PDF占位符失败:', error);
      return {
        success: false,
        error: error.message
      };
    }
  }

  // 生成占位符HTML内容
  generatePlaceholderHtml(originalName, documentType, fileSize) {
    // 使用编码后的文件名作为URL，避免特殊字符问题
    const originalFileUrl = `/uploads/${encodeURIComponent(path.basename(originalName))}`;
    
    return `
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>PDF预览 - ${originalName}</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            display: flex;
            align-items: center;
            justify-content: center;
            padding: 20px;
        }
        
        .pdf-placeholder {
            background: white;
            border-radius: 16px;
            box-shadow: 0 20px 40px rgba(0,0,0,0.1);
            padding: 40px;
            text-align: center;
            max-width: 600px;
            width: 100%;
            position: relative;
            overflow: hidden;
        }
        
        .pdf-placeholder::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            height: 4px;
            background: linear-gradient(90deg, #667eea, #764ba2);
        }
        
        .pdf-icon {
            font-size: 80px;
            margin-bottom: 24px;
            animation: bounce 2s infinite;
        }
        
        @keyframes bounce {
            0%, 20%, 50%, 80%, 100% { transform: translateY(0); }
            40% { transform: translateY(-10px); }
            60% { transform: translateY(-5px); }
        }
        
        .pdf-title {
            color: #333;
            font-size: 28px;
            font-weight: 700;
            margin-bottom: 12px;
            word-break: break-word;
        }
        
        .pdf-subtitle {
            color: #666;
            font-size: 18px;
            margin-bottom: 24px;
        }
        
        .pdf-description {
            color: #888;
            font-size: 16px;
            line-height: 1.6;
            margin-bottom: 32px;
            padding: 0 20px;
        }
        
        .pdf-actions {
            display: flex;
            gap: 16px;
            justify-content: center;
            flex-wrap: wrap;
            margin-bottom: 32px;
        }
        
        .pdf-action {
            display: inline-flex;
            align-items: center;
            gap: 8px;
            padding: 12px 24px;
            background: linear-gradient(135deg, #667eea, #764ba2);
            color: white;
            text-decoration: none;
            border-radius: 8px;
            font-weight: 600;
            font-size: 16px;
            transition: all 0.3s ease;
            box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
        }
        
        .pdf-action:hover {
            transform: translateY(-2px);
            box-shadow: 0 6px 20px rgba(102, 126, 234, 0.4);
            color: white;
        }
        
        .pdf-action.secondary {
            background: #f8f9fa;
            color: #333;
            box-shadow: 0 4px 12px rgba(0,0,0,0.1);
        }
        
        .pdf-action.secondary:hover {
            background: #e9ecef;
            color: #333;
            box-shadow: 0 6px 20px rgba(0,0,0,0.15);
        }
        
        .pdf-info {
            background: #f8f9fa;
            border-radius: 12px;
            padding: 24px;
            margin-top: 24px;
        }
        
        .pdf-info-title {
            color: #333;
            font-size: 18px;
            font-weight: 600;
            margin-bottom: 16px;
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 8px;
        }
        
        .pdf-stats {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
            gap: 16px;
            margin-bottom: 20px;
        }
        
        .pdf-stat {
            background: white;
            padding: 16px;
            border-radius: 8px;
            box-shadow: 0 2px 8px rgba(0,0,0,0.05);
        }
        
        .pdf-stat-icon {
            font-size: 24px;
            margin-bottom: 8px;
        }
        
        .pdf-stat-label {
            font-size: 12px;
            color: #666;
            margin-bottom: 4px;
        }
        
        .pdf-stat-value {
            font-size: 16px;
            font-weight: 600;
            color: #333;
        }
        
        .pdf-note {
            color: #666;
            font-size: 14px;
            line-height: 1.5;
            background: rgba(102, 126, 234, 0.1);
            padding: 16px;
            border-radius: 8px;
            border-left: 4px solid #667eea;
        }
        
        @media (max-width: 768px) {
            .pdf-placeholder {
                padding: 24px;
                margin: 10px;
            }
            
            .pdf-title {
                font-size: 24px;
            }
            
            .pdf-actions {
                flex-direction: column;
            }
            
            .pdf-action {
                width: 100%;
                justify-content: center;
            }
        }
    </style>
</head>
<body>
    <div class="pdf-placeholder">
        <div class="pdf-icon">📄</div>
        <h1 class="pdf-title">${originalName}</h1>
        <p class="pdf-subtitle">${documentType} → PDF转换</p>
        <p class="pdf-description">
            系统正在处理您的${documentType}文档。为了获得最佳的阅读体验，
            建议您下载原始文件并使用专业软件打开，或等待PDF转换完成。
        </p>
        
        <div class="pdf-actions">
            <a href="${originalFileUrl}" class="pdf-action" download="${originalName}">
                <span>⬇️</span>
                <span>下载原文件</span>
            </a>
            <a href="${originalFileUrl}" target="_blank" class="pdf-action secondary">
                <span>🔗</span>
                <span>在新窗口打开</span>
            </a>
        </div>
        
        <div class="pdf-info">
            <div class="pdf-info-title">
                <span>📊</span>
                <span>文件信息</span>
            </div>
            
            <div class="pdf-stats">
                <div class="pdf-stat">
                    <div class="pdf-stat-icon">📁</div>
                    <div class="pdf-stat-label">文件大小</div>
                    <div class="pdf-stat-value">${fileSize} KB</div>
                </div>
                <div class="pdf-stat">
                    <div class="pdf-stat-icon">📄</div>
                    <div class="pdf-stat-label">文档类型</div>
                    <div class="pdf-stat-value">${documentType}</div>
                </div>
                <div class="pdf-stat">
                    <div class="pdf-stat-icon">🔄</div>
                    <div class="pdf-stat-label">转换状态</div>
                    <div class="pdf-stat-value">处理中</div>
                </div>
            </div>
            
            <div class="pdf-note">
                <strong>💡 提示：</strong> 
                PDF转换功能需要安装LibreOffice/OpenOffice。如果您是系统管理员，
                请安装LibreOffice或OpenOffice以启用自动PDF转换功能。
            </div>
        </div>
    </div>
    
    <script>
        // 自动刷新检查转换状态
        let refreshCount = 0;
        const maxRefresh = 10;
        
        function checkConversionStatus() {
            refreshCount++;
            if (refreshCount < maxRefresh) {
                setTimeout(() => {
                    window.location.reload();
                }, 5000);
            }
        }
        
        // 5秒后开始检查
        setTimeout(checkConversionStatus, 5000);
    </script>
</body>
</html>`;
  }

  // 主转换方法
  async convertToPdf(filePath, originalName, mimeType) {
    try {
      console.log('开始转换文档为PDF:', originalName, mimeType);
      
      let result;
      
      // 根据文件类型选择转换方法
      if (mimeType === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' || 
          mimeType === 'application/msword') {
        // Word文档
        result = await this.convertWordToPdf(filePath, originalName);
      } else if (mimeType === 'application/vnd.openxmlformats-officedocument.presentationml.presentation' || 
                 mimeType === 'application/vnd.ms-powerpoint') {
        // PowerPoint文档
        result = await this.convertPowerPointToPdf(filePath, originalName);
      } else if (mimeType === 'application/pdf') {
        // 已经是PDF文件，直接返回
        result = {
          success: true,
          pdfPath: filePath,
          pdfFileName: path.basename(filePath),
          pdfUrl: `/uploads/${path.basename(filePath)}`,
          originalSize: fs.statSync(filePath).size,
          pdfSize: fs.statSync(filePath).size,
          isOriginalPdf: true
        };
      } else {
        // 不支持的文件类型
        result = {
          success: false,
          error: `不支持转换的文件类型: ${mimeType}`
        };
      }
      
      return result;
    } catch (error) {
      console.error('PDF转换失败:', error);
      return {
        success: false,
        error: error.message
      };
    }
  }

  // 保存PDF转换结果到数据库
  async savePdfConversionResult(userId, originalFileId, pdfPath, pdfUrl, status = 'completed', errorMessage = null) {
    try {
      // 检查是否已存在转换记录
      const checkQuery = `
        SELECT id FROM pdf_conversions 
        WHERE original_file_id = $1
      `;
      
      const checkResult = await pool.query(checkQuery, [originalFileId]);
      
      let query, values;
      
      if (checkResult.rows.length > 0) {
        // 更新现有记录
        query = `
          UPDATE pdf_conversions 
          SET pdf_path = $1, pdf_url = $2, conversion_status = $3, error_message = $4, updated_at = CURRENT_TIMESTAMP
          WHERE original_file_id = $5
          RETURNING *
        `;
        values = [pdfPath, pdfUrl, status, errorMessage, originalFileId];
      } else {
        // 插入新记录
        query = `
          INSERT INTO pdf_conversions (user_id, original_file_id, pdf_path, pdf_url, conversion_status, error_message)
          VALUES ($1, $2, $3, $4, $5, $6)
          RETURNING *
        `;
        values = [userId, originalFileId, pdfPath, pdfUrl, status, errorMessage];
      }
      
      const result = await pool.query(query, values);
      
      return {
        success: true,
        data: result.rows[0]
      };
    } catch (error) {
      console.error('保存PDF转换结果失败:', error);
      return {
        success: false,
        error: error.message
      };
    }
  }

  // 获取PDF转换结果
  async getPdfConversionResult(fileId) {
    try {
      const query = `
        SELECT * FROM pdf_conversions 
        WHERE original_file_id = $1
      `;
      
      const result = await pool.query(query, [fileId]);
      
      if (result.rows.length > 0) {
        return {
          success: true,
          data: result.rows[0]
        };
      } else {
        return {
          success: false,
          message: '未找到转换记录'
        };
      }
    } catch (error) {
      console.error('获取PDF转换结果失败:', error);
      return {
        success: false,
        error: error.message
      };
    }
  }
}

module.exports = new PdfConversionService();